package com.leo.train.business.service.Impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leo.train.business.dto.DailyTrainInfoQueryDto;
import com.leo.train.business.entity.DailyTrainInfo;
import com.leo.train.business.entity.TrainInfo;
import com.leo.train.business.mapper.DailyTrainInfoMapper;
import com.leo.train.business.mapper.TrainInfoMapper;
import com.leo.train.business.service.DailyTrainInfoService;
import com.leo.train.common.exception.BusinessException;
import com.leo.train.common.exception.BusinessExceptionEnum;
import com.leo.train.common.resp.CommonResp;
import com.leo.train.common.resp.PageResult;
import com.leo.train.common.util.SnowUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class DailyTrainInfoServiceImpl implements DailyTrainInfoService {
    @Autowired
    private DailyTrainInfoMapper dailyTrainInfoMapper;
    @Autowired
    private TrainInfoMapper trainInfoMapper;


    /**
     * 保存
     * @param dailyTrainInfo
     */
    @Override
    public void save(DailyTrainInfo dailyTrainInfo) {
        Long id = dailyTrainInfo.getId();
        if(id == null) {
            // 判断唯一键：列车编号+索引
            DailyTrainInfo dailyTrainInfoExist = selectByTrainCodeAndIndexAndDate(dailyTrainInfo.getTrainCode(), dailyTrainInfo.getIndex(), dailyTrainInfo.getDate());
            if(dailyTrainInfoExist != null) {
                throw new BusinessException(BusinessExceptionEnum.BUSINESS_TRAIN_STATION_INDEX_UNIQUE_ERROR);
            }
            // 判断唯一键：列车编号+站名
            DailyTrainInfo dailyTrainInfoExist2 = selectByTrainCodeAndNameAndDate(dailyTrainInfo.getTrainCode(), dailyTrainInfo.getName(), dailyTrainInfo.getDate());
            if(dailyTrainInfoExist2 != null) {
                throw new BusinessException(BusinessExceptionEnum.BUSINESS_TRAIN_STATION_NAME_UNIQUE_ERROR);
            }
            // 新增
            dailyTrainInfo.setId(SnowUtil.getSnowflakeNextId());
            dailyTrainInfo.setCreateTime(new Date());
            dailyTrainInfo.setUpdateTime(new Date());
            dailyTrainInfoMapper.insert(dailyTrainInfo);
        } else {
            // 编辑
            dailyTrainInfo.setUpdateTime(new Date());
            dailyTrainInfoMapper.update(dailyTrainInfo);
        }
    }

    @Override
    public void delete(Long id) {
        dailyTrainInfoMapper.delete(id);
    }

    @Override
    public PageResult<DailyTrainInfo> list(DailyTrainInfoQueryDto dailyTrainInfoQueryDto) {
        PageHelper.startPage(dailyTrainInfoQueryDto.getPage(), dailyTrainInfoQueryDto.getPageSize());
        Page<DailyTrainInfo> page = dailyTrainInfoMapper.list(dailyTrainInfoQueryDto);
        return new PageResult<>(page.getTotal(),page.getResult());
    }

    @Override
    public DailyTrainInfo detail(Long id) {
        DailyTrainInfo dailyTrainInfo =dailyTrainInfoMapper.selectById(id);
        if(dailyTrainInfo == null) {
            throw new BusinessException(BusinessExceptionEnum.BUSINESS_TRAIN_INFO_NOT_EXIST);
        }
        return dailyTrainInfo;
    }


    /**
     * 定义一个唯一键方法
     */
    public DailyTrainInfo selectByTrainCodeAndIndexAndDate(String trainCode, Integer index, Date date) {
        DailyTrainInfo dailyTrainInfo = dailyTrainInfoMapper.selectByTrainCodeAndIndexAndDate(trainCode, index, date);
        if (dailyTrainInfo != null) {
            return dailyTrainInfo;
        }
        return null;
    }

    /**
     * 定义一个唯一键方法
     */
    public DailyTrainInfo selectByTrainCodeAndNameAndDate(String trainCode, String name, Date date) {
        DailyTrainInfo dailyTrainInfo = dailyTrainInfoMapper.selectByTrainCodeAndNameAndDate(trainCode, name, date);
        if (dailyTrainInfo != null) {
            return dailyTrainInfo;
        }
        return null;
    }

    /**
     * 生成某日当前车次的所有车站信息
     * @param date
     * @param trainCode
     */
    public void genDaily(Date date, String trainCode) {
        log.info("生成该车次的所有车站信息开始，trainCode: {}, date: {}", trainCode, DateUtil.formatDate(date));

        // 1. 先删除该日期该车次的所有车站信息
        dailyTrainInfoMapper.deleteByTrainCodeAndDate(trainCode, date);
        // 2. 生成该车次所有车站信息
        // 2.1 查询该车次所有车站信息
        List<TrainInfo> trainInfoList = trainInfoMapper.selectByTrainCode(trainCode);
        if(CollUtil.isEmpty(trainInfoList)) {
            log.info("没有当前车次的车站基础数据，生成该车次的车站信息结束");
            return;
        }
        // 2.2 遍历所有车站信息，保存到数据库
        for (TrainInfo trainInfo : trainInfoList) {
            Date now = new Date();
            DailyTrainInfo dailyTrainInfo = new DailyTrainInfo();
            BeanUtils.copyProperties(trainInfo, dailyTrainInfo);
            dailyTrainInfo.setDate(date);
            dailyTrainInfo.setId(SnowUtil.getSnowflakeNextId());
            dailyTrainInfo.setCreateTime(now);
            dailyTrainInfo.setUpdateTime(now);
            dailyTrainInfoMapper.insert(dailyTrainInfo);
        }
        log.info("生成该车次的所有车站信息结束，trainCode: {}, date: {}", trainCode, DateUtil.formatDate(date));
    }

    @Override
    public CommonResp<List<DailyTrainInfo>> getTrainStation(String trainCode, Date date) {
        // 1. 查询该车次所有车站信息
        List<DailyTrainInfo> dailyTrainInfoList = dailyTrainInfoMapper.selectByTrainCodeAndDate(trainCode, date);
        if(CollUtil.isEmpty(dailyTrainInfoList)) {
            log.info("没有当前车次的车站基础数据，生成该车次的车站信息结束");
            return new CommonResp<>();
        }
        return new CommonResp<>(dailyTrainInfoList);
    }
}
